package com.boboPlanet.comm.result;

//import com.alibaba.fastjson.JSONObject;
import com.boboPlanet.comm.enums.FeignErrorEnum;
import com.boboPlanet.comm.enums.LoginUserErrorEnum;
import com.boboPlanet.comm.enums.PlanetCommCode;
import com.boboPlanet.comm.enums.ResultEnum;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import java.io.Serializable;
import java.util.Collections;

/**
 * @author mis_wu
 * @date 2023-02-12
 * @todo 统一返回封装实体
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@SuppressWarnings("all")
public class ResponseResult<T> implements Serializable{

    static final long serialVersionUID = -7430439691155161871L;

    private static Logger log = LoggerFactory.getLogger(ResponseResult.class);

//    private static JSONObject OBJECT_EMPTY = new JSONObject();


    private Boolean success;
    private String code;
    private String msg;
    private T data;
    private String traceId;

    public static <T> ResponseResult<T> isSuccess(){
        ResponseResult<T> result = new ResponseResult<>();
        result.setSuccess(Boolean.TRUE);
        result.setCode(ResultEnum.RESULT_SUCCESS.getCode());
        result.setMsg(ResultEnum.RESULT_SUCCESS.getMsg());
        result.setData((T) Collections.EMPTY_LIST);
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    public static <T> ResponseResult<T> isSuccess(T data){
        ResponseResult<T> result = new ResponseResult<>();
        result.setSuccess(Boolean.TRUE);
        result.setCode(ResultEnum.RESULT_SUCCESS.getCode());
        result.setMsg(ResultEnum.RESULT_SUCCESS.getMsg());
        result.setData(data);
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    public static <T> ResponseResult<T> isSuccess(String code, String msg, T data){
        ResponseResult<T> result = new ResponseResult<>();
        if (ObjectUtils.isEmpty(code)){
            code = ResultEnum.RESULT_SUCCESS.getCode();
        }
        if (ObjectUtils.isEmpty(msg)){
            msg = ResultEnum.RESULT_SUCCESS.getMsg();
        }
        if (ObjectUtils.isEmpty(data)){
            data = (T) Collections.singletonList(data);
        }
        result.setSuccess(Boolean.TRUE);
        result.setCode(code);
        result.setMsg(msg);
        result.setData(data);
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    public static<T> ResponseResult<T> error(){
        ResponseResult<T> result = new ResponseResult<>();
        result.setSuccess(Boolean.FALSE);
        result.setCode(ResultEnum.RESULT_ERROR.getCode());
        result.setMsg(ResultEnum.RESULT_ERROR.getMsg());
        result.setData((T) Collections.singletonList(Collections.EMPTY_LIST));
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    public static<T> ResponseResult<T> error(String ... error){
        ResponseResult<T> result = new ResponseResult<>();
        result.setSuccess(Boolean.FALSE);
        result.setCode(ResultEnum.RESULT_ERROR.getCode());
        result.setMsg(ResultEnum.RESULT_ERROR.getMsg());
        StringBuilder msg = new StringBuilder();
        String message;
        if (error.length > 0){
            for (String s : error) {
                msg.append(s).append(",");
            }
        }
        if (msg.length() > 0){
            message = msg.substring(0, msg.length() - 1);
            result.setMsg(message);
        }
        result.setData((T) Collections.singletonList(Collections.EMPTY_LIST));
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    /**
     * 错误返回
     * @param error 枚举类
     * @param data 返回data
     * @param msg 除枚举外 其他错误提示
     * @return ResponseResult
     * @param <T>
     */
    public static<T> ResponseResult<T> error(Object error,T data, String ... msg){
        ResponseResult<T> result = new ResponseResult<>();
        StringBuilder val = new StringBuilder();
        String code = "";
        String errorMsg = "";
        if (error instanceof LoginUserErrorEnum){
            if (ObjectUtils.isEmpty(error)){
                code = ResultEnum.SYS_BUSY_AFTER_TRY.getCode();
            }else {
                code = ((LoginUserErrorEnum) error).getCode();
                errorMsg = ((LoginUserErrorEnum) error).getDesc();
            }
        }
        if (error instanceof FeignErrorEnum){
            if (ObjectUtils.isEmpty(error)){
                code = ResultEnum.SYS_BUSY_AFTER_TRY.getCode();
            }else {
                code = ((FeignErrorEnum) error).getCode();
                errorMsg = ((FeignErrorEnum) error).getDesc();
            }
        }
        if (StringUtils.isNotBlank(errorMsg)){
            val.append(errorMsg);
        }
        if (msg != null && msg.length > 0){
            for (String m : msg) {
                if (val.length() > 0){
                    val = val.append(",").append(m);
                }else {
                    val = val.append(m);
                }
            }
        }
        result.setSuccess(Boolean.FALSE);
        result.setCode(code);
        result.setMsg(val.toString());
        result.setData(data);
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    public static<T> ResponseResult<T> error(String code,String error,T data){
        ResponseResult<T> result = new ResponseResult<>();
        if (ObjectUtils.isEmpty(code)){
            code = ResultEnum.RESULT_ERROR.getCode();
        }
        if (ObjectUtils.isEmpty(error)){
            error = ResultEnum.RESULT_ERROR.getMsg();
        }
        if (ObjectUtils.isEmpty(data)){
            data = (T) Collections.EMPTY_LIST;
        }
        result.setSuccess(Boolean.FALSE);
        result.setCode(code);
        result.setMsg(error);
        result.setData(data);
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

    public static<T> ResponseResult<T> feignError(FeignErrorEnum feignErrorEnum, Object throwable){
        ResponseResult<T> result = new ResponseResult<>();
        result.setCode(feignErrorEnum.getCode());
        result.setMsg(feignErrorEnum.getDesc());
        if (throwable instanceof Throwable){
            result.setData((T) ((Throwable) throwable).getMessage());
        }else {
            result.setData((T) throwable);
        }
        result.setSuccess(Boolean.FALSE);
        result.setTraceId(MDC.get(PlanetCommCode.COMM_LOG_KEY.getCode()));
        return result;
    }

}
